using SqlSugar;
using Rabbit3.Api.Models;
using Rabbit3.Api.Dto;
using AutoMapper;
using Microsoft.Extensions.Caching.Memory;

namespace Rabbit3.Api.Services
{
    /// <summary>
    /// 优化的溯源信息服务实现
    /// </summary>
    public class OptimizedTraceabilityService : OptimizedBaseService, ITraceabilityService
    {
        public OptimizedTraceabilityService(ISqlSugarClient db, IMapper mapper, IMemoryCache cache, ILogger<OptimizedTraceabilityService> logger)
            : base(db, mapper, cache, logger)
        {
        }

        /// <summary>
        /// 分页查询溯源信息 - 优化版本
        /// </summary>
        public async Task<PagedResponseDto<TraceabilityResponseDto>> GetPagedListAsync(QueryTraceabilityDto queryDto)
        {
            var cacheKey = $"traceability_list_{queryDto.PageIndex}_{queryDto.PageSize}_{queryDto.ProductName}_{queryDto.ProductionBatch}_{queryDto.ProductionEnterprise}_{queryDto.ProductionLicenseNumber}";
            
            return await GetOrSetCacheAsync(cacheKey, async () =>
            {
                var query = _db.Queryable<TraceabilityInfo>()
                    .Where(x => !x.IsDeleted);

                // 优化搜索条件 - 使用索引友好的查询
                if (!string.IsNullOrEmpty(queryDto.ProductName))
                {
                    query = query.Where(x => x.ProductName.Contains(queryDto.ProductName));
                }

                if (!string.IsNullOrEmpty(queryDto.ProductionBatch))
                {
                    query = query.Where(x => x.ProductionBatch.Contains(queryDto.ProductionBatch));
                }

                if (!string.IsNullOrEmpty(queryDto.ProductionEnterprise))
                {
                    query = query.Where(x => x.ProductionEnterprise.Contains(queryDto.ProductionEnterprise));
                }

                if (!string.IsNullOrEmpty(queryDto.ProductionLicenseNumber))
                {
                    query = query.Where(x => x.ProductionLicenseNumber.Contains(queryDto.ProductionLicenseNumber));
                }

                // 并行执行总数查询和数据查询
                var (data, totalCount) = await GetPagedDataAsync(query, queryDto.PageIndex, queryDto.PageSize);

                // 映射为DTO
                var responseList = _mapper.Map<List<TraceabilityResponseDto>>(data);

                return new PagedResponseDto<TraceabilityResponseDto>
                {
                    Data = responseList,
                    TotalCount = totalCount,
                    TotalPages = (int)Math.Ceiling((double)totalCount / queryDto.PageSize),
                    PageIndex = queryDto.PageIndex,
                    PageSize = queryDto.PageSize
                };
            }, SHORT_CACHE_EXPIRY) ?? new PagedResponseDto<TraceabilityResponseDto>();
        }

        /// <summary>
        /// 根据ID获取溯源信息 - 优化版本
        /// </summary>
        public async Task<TraceabilityResponseDto?> GetByIdAsync(int id)
        {
            var cacheKey = $"{CACHE_PREFIX_TRACEABILITY}{id}";
            
            return await GetOrSetCacheAsync(cacheKey, async () =>
            {
                var entity = await _db.Queryable<TraceabilityInfo>()
                    .Where(x => x.Id == id && !x.IsDeleted)
                    .FirstAsync();

                return entity == null ? null : _mapper.Map<TraceabilityResponseDto>(entity);
            });
        }

        /// <summary>
        /// 创建溯源信息 - 优化版本
        /// </summary>
        public async Task<TraceabilityResponseDto> CreateAsync(CreateTraceabilityDto createDto)
        {
            var entity = _mapper.Map<TraceabilityInfo>(createDto);
            
            var id = await _db.Insertable(entity).ExecuteReturnIdentityAsync();
            entity.Id = id;

            // 清除相关缓存
            RemoveCachePattern($"{CACHE_PREFIX_TRACEABILITY}list_");

            return _mapper.Map<TraceabilityResponseDto>(entity);
        }

        /// <summary>
        /// 更新溯源信息 - 优化版本
        /// </summary>
        public async Task<TraceabilityResponseDto?> UpdateAsync(UpdateTraceabilityDto updateDto)
        {
            var entity = await _db.Queryable<TraceabilityInfo>()
                .Where(x => x.Id == updateDto.Id && !x.IsDeleted)
                .FirstAsync();

            if (entity == null)
                return null;

            _mapper.Map(updateDto, entity);
            
            await _db.Updateable(entity).ExecuteCommandAsync();

            // 清除相关缓存
            RemoveCache($"{CACHE_PREFIX_TRACEABILITY}{updateDto.Id}");
            RemoveCachePattern($"{CACHE_PREFIX_TRACEABILITY}list_");

            return _mapper.Map<TraceabilityResponseDto>(entity);
        }

        /// <summary>
        /// 删除溯源信息 - 优化版本
        /// </summary>
        public async Task<bool> DeleteAsync(int id)
        {
            var result = await _db.Updateable<TraceabilityInfo>()
                .SetColumns(x => new TraceabilityInfo { IsDeleted = true, UpdatedAt = DateTime.Now })
                .Where(x => x.Id == id && !x.IsDeleted)
                .ExecuteCommandAsync();

            if (result > 0)
            {
                // 清除相关缓存
                RemoveCache($"{CACHE_PREFIX_TRACEABILITY}{id}");
                RemoveCachePattern($"{CACHE_PREFIX_TRACEABILITY}list_");
            }

            return result > 0;
        }

        /// <summary>
        /// 批量删除溯源信息 - 优化版本
        /// </summary>
        public async Task<bool> BatchDeleteAsync(List<int> ids)
        {
            var result = await _db.Updateable<TraceabilityInfo>()
                .SetColumns(x => new TraceabilityInfo { IsDeleted = true, UpdatedAt = DateTime.Now })
                .Where(x => ids.Contains(x.Id) && !x.IsDeleted)
                .ExecuteCommandAsync();

            if (result > 0)
            {
                // 清除相关缓存
                foreach (var id in ids)
                {
                    RemoveCache($"{CACHE_PREFIX_TRACEABILITY}{id}");
                }
                RemoveCachePattern($"{CACHE_PREFIX_TRACEABILITY}list_");
            }

            return result > 0;
        }

        /// <summary>
        /// 导出溯源码 - 优化版本
        /// </summary>
        public async Task<string?> ExportTraceabilityCodeAsync(int id)
        {
            var cacheKey = $"{CACHE_PREFIX_TRACEABILITY}code_{id}";
            
            return await GetOrSetCacheAsync(cacheKey, async () =>
            {
                var entity = await _db.Queryable<TraceabilityInfo>()
                    .Where(x => x.Id == id && !x.IsDeleted)
                    .Select(x => x.TraceabilityCode)
                    .FirstAsync();

                return entity;
            }, SHORT_CACHE_EXPIRY);
        }

        /// <summary>
        /// 计算溯源信息完整度 - 优化版本
        /// </summary>
        public async Task<int> CalculateCompletenessAsync(int traceabilityId)
        {
            var cacheKey = $"{CACHE_PREFIX_TRACEABILITY}completeness_{traceabilityId}";
            
            // 检查缓存
            if (_cache.TryGetValue(cacheKey, out int cachedValue))
            {
                return cachedValue;
            }

            // 并行查询所有相关信息
            var (farmingInfo, slaughterInfo, processingInfo, enterpriseCount, supplierCount) = 
                await ExecuteParallelAsync(
                    () => _db.Queryable<FarmingInfo>()
                        .Where(x => x.TraceabilityId == traceabilityId && !x.IsDeleted)
                        .FirstAsync(),
                    () => _db.Queryable<SlaughterInfo>()
                        .Where(x => x.TraceabilityId == traceabilityId && !x.IsDeleted)
                        .FirstAsync(),
                    () => _db.Queryable<ProcessingInfo>()
                        .Where(x => x.TraceabilityId == traceabilityId && !x.IsDeleted)
                        .FirstAsync(),
                    () => _db.Queryable<EnterpriseInfo>()
                        .Where(x => x.TraceabilityId == traceabilityId && !x.IsDeleted)
                        .CountAsync(),
                    () => _db.Queryable<SupplierInfo>()
                        .Where(x => x.TraceabilityId == traceabilityId && !x.IsDeleted)
                        .CountAsync()
                );

            int totalSteps = 5;
            int completedSteps = 0;

            if (farmingInfo != null) completedSteps++;
            if (slaughterInfo != null) completedSteps++;
            if (processingInfo != null) completedSteps++;
            if (enterpriseCount > 0) completedSteps++;
            if (supplierCount > 0) completedSteps++;

            int completeness = (int)Math.Round((double)completedSteps / totalSteps * 100);

            // 更新溯源信息的完整度
            await _db.Updateable<TraceabilityInfo>()
                .SetColumns(x => new TraceabilityInfo { InformationCompleteness = completeness, UpdatedAt = DateTime.Now })
                .Where(x => x.Id == traceabilityId && !x.IsDeleted)
                .ExecuteCommandAsync();

            // 设置缓存
            _cache.Set(cacheKey, completeness, SHORT_CACHE_EXPIRY);

            return completeness;
        }
    }
}
